package com.axend.lib_base.utils

import android.content.ContentResolver
import android.net.Uri
import android.os.Build.VERSION
import android.os.Environment
import android.util.Log
import com.axend.lib_base.bean.RadarBpmData
import com.axend.lib_base.bean.RadarData
import com.axend.lib_base.help.otgserial.SerialManage
import java.io.File
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
import java.nio.charset.StandardCharsets
import java.util.concurrent.BlockingQueue
import java.util.concurrent.ExecutorService
import java.util.concurrent.LinkedBlockingQueue

object FileOutputUtil {

    const val countNum = 200 // 每50ms写一次数据（雷达发送数据周期50ms）
    const val radarDataInterval = 12000 //一个文件存储10分钟12000组数据后重新创建文件

    const val countNum_bpm = 1200 // 1分钟=60s=1200*50ms：每50ms写一次数据（雷达发送数据周期50ms）
    const val countNum_bpm_write = 1 // 队列中有一组数据后，将数据写入文件（每隔一分钟将一组数据写入文件）
    var isFileCreated_bpm = false

    private var filePath_radar: String = ""
    private var filePath_bpm: String = ""


    // 接收了多少组雷达数据
    @Volatile
    private var dataCount = 0
    @Volatile
    private var dataCount_write = 0

    @Volatile
    private var dataCount_bpm = 0
    @Volatile
    private var dataCount_write_bpm = 0

    var dataQueue_bpm: BlockingQueue<RadarBpmData> = LinkedBlockingQueue()
    var dataQueue_radar: BlockingQueue<RadarData> = LinkedBlockingQueue()

    /**
     * 创建并返回一个文件对象，如果文件不存在则创建。
     *
     * @param fileName 文件名。
     * @return 文件对象。
     */
    private fun createOrGetFile(fileName: String): File {
        val filePath = if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
            CommUtils.getContext()
                .getExternalFilesDir(null)?.absolutePath + "/${fileName}.txt"
        } else {
            CommUtils.getContext().applicationContext.filesDir.absolutePath + "/${fileName}.txt"
        }

        val file = File(filePath)
        if (!file.exists()) {
            try {
                // 确保父目录存在
                file.parentFile?.mkdirs()

                // 创建文件
                if (!file.createNewFile()) {
                    throw IOException("Failed to create file: ${file.path}")
                }
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        return file
    }


    /**
     * 写入头部到文件
     */
    fun writeHeadToFile(fileName: String, content: String) {
        val filePath = if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
            CommUtils.getContext()
                .getExternalFilesDir(null)?.absolutePath + "/${fileName}.txt"
        } else {
            CommUtils.getContext().applicationContext.filesDir.absolutePath + "/${fileName}.txt"
        }
        var file = File(filePath)
        if (file.exists()) return else if (isFileExistsApi29(file.absolutePath)) return
        file = createOrGetFile(fileName)
        try {
            Log.d("writeHeadToFile", filePath)
            FileOutputStream(file).use { fos ->
                fos.write(content.toByteArray(StandardCharsets.UTF_8))
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    /**
     * 写入文本到文件。
     *
     * @param fileName 文件名。
     * @param content 要写入的内容。
     */
    fun writeTextToFile(fileName: String, content: String) {
        val file = createOrGetFile(fileName)
        try {
            FileOutputStream(file, true).use { fos ->
                fos.write(content.toByteArray(StandardCharsets.UTF_8))
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    private fun isFileExistsApi29(filePath: String): Boolean {
        return if (VERSION.SDK_INT >= 29) {
            try {
                val uri = Uri.parse(filePath)
                val cr: ContentResolver = CommUtils.getContext().contentResolver
                val afd = cr.openAssetFileDescriptor(uri, "r")
                if (afd == null) {
                    false
                } else {
                    try {
                        afd.close()
                    } catch (var5: IOException) {
                    }
                    true
                }
            } catch (var6: FileNotFoundException) {
                false
            }
        } else {
            false
        }
    }

    /*
    * 添加雷达数据到队列中，每50ms写入一次数据，每10分钟写入一次文件
    * */
    fun addRadarData(data: RadarData) {
        dataQueue_radar.add(data)
        dataCount += 1
        dataCount_write += 1
        if (dataCount == 1) {
            // 每隔10分钟创建文件
            filePath_radar = "radar${File.separator}radar_${DateUtils.getCurrentFileTimeStamp()}"
            val title =
                "breathing\toutputFilterBreathOut\theartBeating\toutputFilterHeartOut\tdistance\tobjSignal\tsleepStage\tbodyMoveEn\tbodyMoveRange\tTime\r\n"
            writeHeadToFile(filePath_radar, "")
            // 当雷达数据达到radarDataInterval=12000组（10分钟接收到的数据量）时，dataCount重置为0
        } else if (dataCount == radarDataInterval) {
            dataCount = 0 // 重置dataCount
        }
    }

    fun addRadarBpmData(data: RadarBpmData) {
        dataCount_bpm += 1
        dataCount_write_bpm += 1
        if (dataCount_bpm == 1) {
            dataQueue_bpm.add(data)
            // 创建雷达呼吸和心率的表头和文件，只创建一次
            if (!isFileCreated_bpm) {
                filePath_bpm = "radar${File.separator}bpm_${DateUtils.getCurrentFileTimeStamp()}"
                val title = "breathingBpm\theartBeatingBpm\tTime\r\n"
                writeHeadToFile(filePath_bpm, title)
                isFileCreated_bpm = true // 标记文件已创建
            }
            dataCount_write_bpm += 1
            Log.d("dataCount_write_bpm：", Integer.toString(dataCount_write_bpm))
        } else if (dataCount_bpm == countNum_bpm) {
            dataCount_bpm = 0
            Log.d("dataCount_bpm：", Integer.toString(dataCount_bpm))
        }
    }


    fun saveRadarData(executorService: ExecutorService) {
        executorService.execute {
            try {
                while (!Thread.currentThread().isInterrupted) {
                  synchronized(this){
                      // 当队列数据大小等于countNum=200组时，将数据写入文件
                      if (dataCount_write >= countNum) {
                          dataCount_write = 0
                          val radarDataStr = StringBuilder()
                          var i = 0
                          while (i < countNum && !dataQueue_radar.isEmpty()) {
                              val radarData = dataQueue_radar.take()
                              radarDataStr.append(radarDataJoinToString(radarData))
                              i++
                          }
                          writeTextToFile(filePath_radar, radarDataStr.toString())

                          // 当雷达USB连接断开时，将dataCount_write<countNum时的数据写入文件中
//                        } else if (!USBTransferUtil.isConnectUSB && dataCount_write > 0) {
//                            StringBuilder radarDataStr = new StringBuilder();
//                            for (int i = 0; i < dataCount_write && !dataQueue_radar.isEmpty(); i++) {
//                                RadarData radarData = dataQueue_radar.take();
//                                radarDataStr.append(radarDataJoinToString(radarData));
//                            }
//                            writeLogFile_radar(radarDataStr.toString());
//                            dataCount_write = 0;
//                        }
                          // 雷达串口连接断开时，将dataCount_write<countNum时的数据写入文件中
                      } else if (!SerialManage.getInstance().isConnect && dataCount_write > 0) {
                          val radarDataStr = StringBuilder()
                          var i = 0
                          while (i < dataCount_write && !dataQueue_radar.isEmpty()) {
                              val radarData = dataQueue_radar.take()
                              radarDataStr.append(radarDataJoinToString(radarData))
                              i++
                          }
                          writeTextToFile(filePath_radar,radarDataStr.toString())
                          dataCount_write = 0
                      }
                  }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }


    fun saveRadarBpmData(executorService: ExecutorService) {
        isFileCreated_bpm=false
        executorService.execute {
            try {
                while (!Thread.currentThread().isInterrupted) {
                    // 当队列数据大小等于countNum_bpm_write=1组数据时，将数据写入文件

                   synchronized(this){
                       // 当队列数据大小等于countNum_bpm_write=1组数据时，将数据写入文件
                       if (dataCount_write_bpm >= countNum_bpm_write) {
                           dataCount_write_bpm = 0
                           val radarDataBmpStr = java.lang.StringBuilder()
                           var i = 0
                           while (i < countNum_bpm_write && !dataQueue_bpm.isEmpty()) {
                               val radarBpmData = dataQueue_bpm.take()
                               radarDataBmpStr.append(radarBpmDataJoinToString(radarBpmData))
                               i++
                           }
                           writeTextToFile(filePath_bpm,radarDataBmpStr.toString())

                           // 当雷达USB连接断开时，将dataCount_write_bpm<countNum_bpm_write时的数据写入文件中
//                        } else if (!USBTransferUtil.isConnectUSB && dataCount_write_bpm > 0) {
//                            StringBuilder radarDataBmpStr = new StringBuilder();
//
//                            for (int i = 0; i < dataCount_write_bpm && !dataQueue_bpm.isEmpty(); i++) {
//                                RadarBpmData radarBpmData = dataQueue_bpm.take();
//                                radarDataBmpStr.append(radarBpmDataJoinToString(radarBpmData));
//                            }
//                            writeLogFile_bpm(radarDataBmpStr.toString());
//                            dataCount_write_bpm = 0;
//                        }
                           // 雷达串口连接断开时，将dataCount_write_bpm<countNum_bpm_write时的数据写入文件中
                       } else if (!SerialManage.getInstance().isConnect && dataCount_write_bpm > 0) {
                           val radarDataBmpStr = java.lang.StringBuilder()
                           var i = 0
                           while (i < dataCount_write_bpm && !dataQueue_bpm.isEmpty()) {
                               val radarBpmData = dataQueue_bpm.take()
                               radarDataBmpStr.append(radarBpmDataJoinToString(radarBpmData))
                               i++
                           }
                           writeTextToFile(filePath_bpm,radarDataBmpStr.toString())
                           dataCount_write_bpm = 0
                       }
                   }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

     fun saveTempData(fileName: String,content: String){
        val title =
            "Time\tFoucsTemp\tShutterTemp\tEnvTemp\tBodyCenterTemp\tVivoCenterTemp\tBodyMaxTemp\tVivoMaxTemp\tFilteredMaxTemp\tisCalTempOk\tMaxX\tMaxY\r\n"
        writeHeadToFile(fileName,title)
        writeTextToFile(fileName,content)

    }

    /**
     * 保存触发警报信息
     */
    fun saveWarningData(content: String) {
        val title =
            "Time\tnotifyType\tvalue\tmaxValue\tminValue\r\n"
        val fileName="notify${File.separator}notify_${DateUtils.getCurrentDate()}"
        writeHeadToFile(fileName,title)
        writeTextToFile(fileName,content)
    }


    /**
     * 保存红外监测移植
     */
    fun saveMoveTempData(fileName: String,content: String) {
        val title =
            "Time\ttempMeasure\tvivoMaxTemp\tmaxTempArray\r\n"
        writeHeadToFile(fileName,title)
        writeTextToFile(fileName,content)
    }



    private fun radarDataJoinToString(radarData: RadarData): String {
        val TAB = ","
        val NEWLINE = "\r\n"

        val sb = StringBuilder()
        sb.append(radarData.breathStr).append(TAB)
        sb.append(radarData.outputFilterBreathOutStr).append(TAB)
        sb.append(radarData.heartStr).append(TAB)
        sb.append(radarData.outputFilterHeartOutStr).append(TAB)
        sb.append(radarData.distanceStr).append(TAB)
        sb.append(radarData.objSignalStr).append(TAB)
        sb.append(radarData.sleepStageStr).append(TAB)
        sb.append(radarData.bodyMoveEnStr).append(TAB)
        sb.append(radarData.bodyMoveRangeStr).append(TAB)
        sb.append(radarData.dateStr).append(NEWLINE)

        return sb.toString()
    }


    private fun radarBpmDataJoinToString(radarBpmData: RadarBpmData): String {
        val TAB = "\t"
        val NEWLINE = "\r\n"

        val sb = StringBuilder()
        sb.append(radarBpmData.breathBmpStr).append(TAB)
        sb.append(radarBpmData.heartBmpStr).append(TAB)
        sb.append(radarBpmData.dateBmpStr).append(NEWLINE)

        return sb.toString()
    }

}